################################################################################
##
## Filename:	Makefile
## {{{
## Project:	Zip CPU -- a small, lightweight, RISC CPU soft core
##
## Purpose:	This make file is used to finish the configuration of mcy
##		as applied to the ZipCPU.
##
##	Targets include:
##
##		clean	Purge any remaining mutation coverage artifacts, and
##			remove any files copied from elsewhere in the
##			repository
##
##		copy	Make local copies of the files we need to do mutation
##			coverage
##
##		init	An abbreviation for "mcy init"
##		run	An abbreviation for "mcy run"
##		gui	An abbreviation for "mcy gui"
##
##
## Creator:	Dan Gisselquist, Ph.D.
##		Gisselquist Technology, LLC
##
################################################################################
## }}}
## Copyright (C) 2019-2022, Gisselquist Technology, LLC
## {{{
## This program is free software (firmware): you can redistribute it and/or
## modify it under the terms of  the GNU General Public License as published
## by the Free Software Foundation, either version 3 of the License, or (at
## your option) any later version.
##
## This program is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
## for more details.
##
## You should have received a copy of the GNU General Public License along
## with this program.  (It's in the $(ROOT)/doc directory.  Run make with no
## target there if the PDF file isn't present.)  If not, see
## <http://www.gnu.org/licenses/> for a copy.
## }}}
## License:	GPL, v3, as defined and found on www.gnu.org,
## {{{
##		http://www.gnu.org/licenses/gpl.html
##
################################################################################
##
## }}}
.PHONY: all clean copy init run gui
all: run

MAKE ?= make	# Was `which make`
MCY  ?= mcy
SUBMAKE := $(MAKE) --no-print-directory -C
RTL  := ../../../rtl
CORE := $(RTL)/core
SIM  := ../../../sim/verilator
ASM  := ../../asm/
ZASM := ../../../sw/zasm/
VSRC := cpuops.v dblfetch.v dcache.v div.v idecode.v iscachable.v memops.v   \
	mpyop.v pfcache.v pipefetch.v pipemem.v prefetch.v slowmpy.v zipcpu.v
CSRC := testb.h byteswap.h byteswap.cpp memsim.h memsim.cpp twoc.h twoc.cpp \
	zipelf.h zipelf.cpp zopcodes.h zopcodes.cpp

.PHONY: clean
clean:
	@echo "Cleaning up mcy artifacts"
	mcy purge
	# Remove the database and tasks directories, in case something went
	# wrong with "mcy purge"
	rm -rf database/ tasks/
	#
	# Remove the CPU Verilog sources
	rm -f cpudefs.v cpudefs.h
	rm -f $(VSRC) wbdblpriarb.v
	#
	# Remove the C++ Verilator sources
	rm -f testb.h
	rm -f byteswap.cpp byteswap.h
	rm -f memsim.cpp   memsim.h
	rm -f twoc.cpp     twoc.h
	rm -f zipelf.cpp   zipelf.h
	rm -f zopcodes.cpp zopcodes.h
	#
	# Remove our test script
	rm -f simtest

.PHONY: copy
copy: cpudefs.v $(VSRC) $(CSRC) wbdblpriarb.v simtest

#
# Copy the Verilog sources we need from the ZipCPU core directories here
cpuops.v: $(CORE)/cpuops.v
	cp $(CORE)/cpuops.v .
dblfetch.v: $(CORE)/dblfetch.v
	cp $(CORE)/dblfetch.v .
dcache.v: $(CORE)/dcache.v
	cp $(CORE)/dcache.v .
div.v: $(CORE)/div.v
	cp $(CORE)/div.v .
idecode.v: $(CORE)/idecode.v
	cp $(CORE)/idecode.v .
iscachable.v: $(CORE)/iscachable.v
	cp $(CORE)/iscachable.v .
memops.v: $(CORE)/memops.v
	cp $(CORE)/memops.v .
mpyop.v: $(CORE)/mpyop.v
	cp $(CORE)/mpyop.v .
pfcache.v: $(CORE)/pfcache.v
	cp $(CORE)/pfcache.v .
pipefetch.v: $(CORE)/pipefetch.v
	cp $(CORE)/pipefetch.v .
pipemem.v: $(CORE)/pipemem.v
	cp $(CORE)/pipemem.v .
prefetch.v: $(CORE)/prefetch.v
	cp $(CORE)/prefetch.v .
slowmpy.v: $(CORE)/slowmpy.v
	cp $(CORE)/slowmpy.v .
zipcpu.v: $(CORE)/zipcpu.v
	cp $(CORE)/zipcpu.v .
# The ZipCPU core also depends upon a WB arbiter found in a separate directory
# Let's get that too.
wbdblpriarb.v: $(RTL)/ex/wbdblpriarb.v
	cp $(RTL)/ex/wbdblpriarb.v .

#
# Copy the Verilator simulation sources from the $(SIM) directory so we can
# have a copy of them here
testb.h: $(SIM)/testb.h
	cp $(SIM)/testb.h .
byteswap.h: $(SIM)/byteswap.h
	cp $(SIM)/byteswap.h .
byteswap.cpp: $(SIM)/byteswap.cpp
	cp $(SIM)/byteswap.cpp .
memsim.h: $(SIM)/memsim.h
	cp $(SIM)/memsim.h .
memsim.cpp: $(SIM)/memsim.cpp
	cp $(SIM)/memsim.cpp .
twoc.h: $(SIM)/twoc.h
	cp $(SIM)/twoc.h .
twoc.cpp: $(SIM)/twoc.cpp
	cp $(SIM)/twoc.cpp .
zipelf.h: $(SIM)/zipelf.h
	cp $(SIM)/zipelf.h .
zipelf.cpp: $(SIM)/zipelf.cpp
	cp $(SIM)/zipelf.cpp .
zopcodes.h: $(ZASM)/zopcodes.h
	cp $(ZASM)/zopcodes.h .
zopcodes.cpp: $(ZASM)/zopcodes.cpp
	cp $(ZASM)/zopcodes.cpp .

cpudefs.v: # Can't depend upon the original if we want to try out changes
	cp $(RTL)/cpudefs.v .

cpudefs.h: cpudefs.v
	@echo "Building cpudefs.h"
	@echo "// " > $@
	@echo "// Do not edit this file, it is automatically generated!" >> $@
	@echo "// To generate this file, \"make cpudefs.h\" in the rtl directory." >> $@
	@echo "// " >> $@
	@grep "^\`" $^ | sed -e '{ s/^`/#/ }' >> $@

simtest: $(ASM)/simtest
	cp $(ASM)/simtest .

database/mutations.txt: config.mcy
	mcy init

init: database/mutations.txt cpudefs.h simtest copy

run: simtest $(VSRC) $(CSRC) database/mutations.txt
	mcy run # -j <ncpus>

gui:
	mcy gui

status:
	mcy status

#
# You may want to run a test-run before starting, since it can be disappointing
# to get hours into the process only to find a bug and then need to start
# over
test: init
	@echo; echo; echo "Testing the Verilator simulation" ; echo
	mcy task -v -k sim_verilator 2
	@echo; echo; echo "Testing the BMC pass" ; echo
	mcy task -v -k eq_bmc 2
	@echo; echo; echo "Testing the simulation pass" ; echo
	mcy task -v -k eq_sim3 30 2
	@echo; echo; echo
	@echo "All tests passed, feel free to run: make run"
